#include "mysqlclient.hpp"
#include "logger.h"

namespace moqi
{

    MySQLClient::MySQLClient()
    {
        init();
    }
    MySQLClient::~MySQLClient()
    {
        mysql_close(&_conn);
    }
    void MySQLClient::init()
    {
        if (mysql_init(&_conn) == nullptr)
            perror("Failed to init MySQL");
    }
    void MySQLClient::connect(const char *host,
                              const char *user,
                              const char *password,
                              const char *db,
                              unsigned short port)
    {

        if (!mysql_real_connect(&_conn, host, user, password, db, port, NULL, 0))
        {
            LOG_ERROR("Failed to connect to database: Error: %s", mysql_error(&_conn));
        }
    }
    bool MySQLClient::writeOperationQuery(const string &sql)
    {
        int ret = mysql_real_query(&_conn, sql.c_str(), sql.size());
        if (ret != 0)
        {
            LOG_ERROR("File to query errno: %u, %s", mysql_errno(&_conn), mysql_error(&_conn));
            return false;
        }
        LOG_INFO("Query OK, %ld row affected", mysql_affected_rows(&_conn));
        return true;
    }

    vector<vector<string>> MySQLClient::readOperationQuery(const string &sql)
    {
        vector<vector<string>> ret;
        int flag = mysql_real_query(&_conn, sql.c_str(), sql.size());
        if (flag != 0)
        {
            LOG_ERROR("File to query errno: %u, %s", mysql_errno(&_conn), mysql_error(&_conn));
            return ret;
        }
        MYSQL_RES *res = mysql_store_result(&_conn);
        if (res)
        {
            MYSQL_FIELD *field = nullptr;
            vector<string> fields;
            while ((field = mysql_fetch_field(res)) != nullptr)
            {
                fields.emplace_back(field->name);
            }
            ret.push_back(std::move(fields));

            int rows = mysql_num_rows(res);
            int cols = mysql_num_fields(res);
            MYSQL_ROW row;
            while ((row = mysql_fetch_row(res)) != nullptr)
            {
                vector<string> rowLine;
                for (int i = 0; i < cols; ++i)
                {
                    rowLine.emplace_back(row[i]);
                }
                ret.push_back(std::move(rowLine));
            }
        }

        return ret;
    }

} // end of namespace moqi
